package com.knight.concurrent;

import java.util.Random;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ConditionTest {

	final Lock lock = new ReentrantLock();

	final Condition notFull = lock.newCondition();

	final Condition notEmpty = lock.newCondition();

	final Object[] items = new Object[5];

	int putptr, takeptr, count;

	public void put(Object x) throws InterruptedException {
		lock.lock();
		try {

			while (count == items.length)
				notFull.await();

			items[putptr] = x;
			if (++putptr == items.length)
				putptr = 0;

			++count;
			notEmpty.signal(); // 既然已经放进了元素，肯定不空了，唤醒“notEmpty”
		} finally {
			lock.unlock();
		}
	}

	public Object take() throws InterruptedException {
		lock.lock();
		try {
			while (count == 0)
				notEmpty.await();

			Object x = items[takeptr];
			if (++takeptr == items.length)
				takeptr = 0;

			--count;
			notFull.signal(); // 既然已经拿走了元素，肯定不满了，唤醒“notFull”
			return x;
		} finally {
			lock.unlock();
		}

	}

	public static void main(String[] args) {

		ConditionTest con = new ConditionTest();
		for (int i = 0; i < 10; i++) {

			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						con.put(new String(new Random().nextInt(100) + ""));
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}

		for (int j = 0; j < 10; j++) {
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						System.out.println(con.take());
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}).start();
		}
	}
}
